package com.tang.filecenter.service.impl;

import com.tang.common.feign.BlogHandleFeign;
import com.tang.filecenter.dto.ImageListDto;
import com.tang.filecenter.properties.FtpProperties;
import com.tang.filecenter.service.IGalleryService;
import com.tang.filecenter.vo.ImageVo;
import com.tang.filecenter.vo.PageVo;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class GalleryServiceImpl implements IGalleryService {
    @Autowired
    private FtpProperties ftpProperties;
    @Autowired
    private BlogHandleFeign blogHandleFeign;
    @Value("${server.port}")
    private String port;
    @Value("${server.host}")
    private String url;

    @Override
    public void get(String name, HttpServletResponse response) throws IOException {
        log.info("获取图片【{}】",name);
        FTPClient ftpClient = createFtpClient();
        InputStream inputStream = null;
        try {
            inputStream = ftpClient.retrieveFileStream(new String((ftpProperties.getGalleryPath() + "/" + name).getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
            if (inputStream == null)throw new RuntimeException("图库不存在该图片！");
            response.getOutputStream().write(IOUtils.toByteArray(inputStream));
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
            ftpClient.logout();
            ftpClient.disconnect();
            log.info("FTP客户端已退出！");
        }
    }

    @Override
    public String upload(MultipartFile file) throws IOException {
        if (file == null)throw new RuntimeException("图片不能为空！");
        String name = file.getOriginalFilename();
        log.info("上传图片【{}】",name);
        FTPClient ftpClient = createFtpClient();
        try {
            ftpClient.changeWorkingDirectory(new String(ftpProperties.getGalleryPath().getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
            boolean b = ftpClient.storeFile(new String(name.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1), file.getInputStream());
            if (!b)throw new RuntimeException("图片上传失败！");
            return getImageUrl(name);
        }finally {
            ftpClient.logout();
            ftpClient.disconnect();
            log.info("FTP客户端已退出！");
        }
    }

    @Override
    public void delete(String name) throws IOException {
        log.info("删除图片【{}】",name);
        FTPClient ftpClient = createFtpClient();
        try {
            boolean b = ftpClient.deleteFile(new String((ftpProperties.getGalleryPath() + "/" + name).getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
            if (!b)throw new RuntimeException("删除失败！");
        }finally {
            ftpClient.logout();
            ftpClient.disconnect();
            log.info("FTP客户端已退出！");
        }
    }

    @Override
    public PageVo<ImageVo> pageList(ImageListDto dto) throws IOException {
        log.info("分页查询图片，{}",dto);
        FTPClient ftpClient = createFtpClient();
        int begin = (dto.getCurrent() - 1) * dto.getSize();
        int end = begin + dto.getSize();
        try {
            List<ImageVo> collect = Arrays.stream(ftpClient.listFiles(new String((ftpProperties.getGalleryPath()).getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1))).map(item -> new ImageVo() {{
                setName(item.getName());
                setSize(item.getSize() / 1024 + "KB");
                setUrl(getImageUrl(item.getName()));
            }}).filter(item -> !Arrays.asList(".","..").contains(item.getName())).collect(Collectors.toList());
            List<ImageVo> imageVos = collect.subList(begin, Math.min(end, collect.size()));
            return new PageVo<ImageVo>(){{
                setRecords(imageVos);
                setTotal(collect.size());
            }};
        }finally {
            ftpClient.logout();
            ftpClient.disconnect();
            log.info("FTP客户端已退出！");
        }
    }

    @SneakyThrows
    @Override
    public String uploadForBlog(Integer blogId, MultipartFile file) {
        String upload = upload(file);
        blogHandleFeign.save(blogId, file.getOriginalFilename());
        return upload;
    }

    /**
     * 创建Ftp连接
     */
    private FTPClient createFtpClient(){
        FTPClient ftpClient = new FTPClient();
        try {
            ftpClient.connect(ftpProperties.getHost(), ftpProperties.getPort());
            ftpClient.login(ftpProperties.getUsername(),ftpProperties.getPassword());
            int reply = ftpClient.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)){
                ftpClient.disconnect();
                throw new RuntimeException("连接Ftp服务器失败！") ;
            }
            log.info("连接Ftp服务器成功");
            // 开启服务器对UTF-8的支持
            ftpClient.setControlEncoding("UTF-8");
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            ftpClient.enterLocalPassiveMode();
        }catch (Exception e){
            log.error("连接ftp服务器异常！",e);
        }
        return ftpClient;
    }

    /**
     * 拼接url
     */
    private String getImageUrl(String name){
        return "http://" + url + ":" + port + "/fileCenter/gallery/get/" + name;
    }
}
